﻿using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace IoTSignalR
{
    //中介者模式
    public class ProtocolMediator
    {
        //协议集合
        public ConcurrentDictionary<ProtocolEnum, IGeneralPipeProtocol> _protocols = new ConcurrentDictionary<ProtocolEnum, IGeneralPipeProtocol>();
        //连接标识与协议映射
        private ConcurrentDictionary<string, ProtocolEnum> _clientIdProtocolMap = new ConcurrentDictionary<string, ProtocolEnum>();
        //原子统计监控
        private ConcurrentDictionary<ProtocolEnum, int> _protocolSendCount = new ConcurrentDictionary<ProtocolEnum, int>();
        private ConcurrentDictionary<ProtocolEnum, int> _protocolReceivedCount = new ConcurrentDictionary<ProtocolEnum, int>();
        private ConcurrentDictionary<ProtocolEnum, int> _protocolConnectCount = new ConcurrentDictionary<ProtocolEnum, int>();
        public void RegisterProtocol(ProtocolEnum protocolName, IGeneralPipeProtocol protocol)
        {
            protocol.OnConnectedAfter += (sender, arg) =>
            {
                _clientIdProtocolMap.TryAdd(arg.ClientId, arg.Protocol);
                _protocolConnectCount.AddOrUpdate(arg.Protocol, 1, (key, oldValue) => Interlocked.Increment(ref oldValue));
                Console.WriteLine($"{arg.Protocol}协议连接成功,连接标识{arg.ClientId}，当前连接数：{_protocolConnectCount[arg.Protocol]}");
            };
            protocol.OnDisconnectedAfter += (sender, arg) =>
            {
                _clientIdProtocolMap.TryRemove(arg.ClientId, out _);
                _protocolConnectCount.AddOrUpdate(arg.Protocol, 1, (key, oldValue) => Interlocked.Decrement(ref oldValue));
                Console.WriteLine($"{arg.Protocol}协议断开连接，当前连接数：{_protocolConnectCount[arg.Protocol]}");
            };
            protocol.ReceiveMessagesAfter += async (sender, arg) =>
            {
                _protocolReceivedCount.AddOrUpdate(arg.Protocol, 1, (key, oldValue) => Interlocked.Increment(ref oldValue));
                Console.WriteLine($"{arg.Protocol}协议收到消息：消息连接{arg.ClientId},消息内容:{arg.Message},消息数量:{_protocolReceivedCount[arg.Protocol]}");
                var msgSplit = arg.Message.Split('$');
                if (msgSplit.Length == 2)
                {
                    await this.SendMsg(msgSplit[0], msgSplit[1]);
                    Console.WriteLine("中介者协调不同协议转发消息");

                }
                else
                {
                    Console.WriteLine("请采用$分割对方的标识和你的消息主体");
                }
            };
            protocol.SendMessagesAfter += (sender, arg) =>
            {
                _protocolSendCount.AddOrUpdate(arg.Protocol, 1, (key, oldValue) => Interlocked.Increment(ref oldValue));
                Console.WriteLine($"{arg.Protocol}协议发送消息：消息连接{arg.ClientId},消息内容:{arg.Message},消息数量:{_protocolSendCount[arg.Protocol]}");
            };
            _protocols.TryAdd(protocolName, protocol);
        }
        //对方的连接标识
        public async Task SendMsg(string clientId, string msg)
        {
            if (this._clientIdProtocolMap.TryGetValue(clientId,out ProtocolEnum protocolEnum))
            {
                if (_protocols.TryGetValue(protocolEnum,out var generalPipeProtocol))
                {
                    await generalPipeProtocol.SendMsg(clientId, msg);
                }
            }
        }
        public async Task SendGroupMsg(ProtocolEnum protocolName, string clientId, string msg)
        {
            if (_protocols.ContainsKey(protocolName))
            {
                await _protocols[protocolName].SendGroupMsg(clientId, msg);
            }
        }
    }
}
